#include <QBoxLayout>
#include <QCommonStyle>

#include "PlaylistGuiFactory.h"
#include "IF_MediaEngineInterface.h"
#include "mediaPositionSlider.h"
#include "AudioVideoAutomation.h"
#include "PictureAutomation.h"
#include "volumeslider.h"
#include "FullScreenVideoWidget.h"
#include "PlaylistView.h"
#include "ActionListController.h"
#include "playlistPainter.h"
#include "AudioVideoPlayBar.h"
#include "PicturePlaybar.h"
#include "PlaylistBar.h"
#include "ApplicationIcon.h"
#include "QSpinBox"
#include "FileInport.h"
#include "testableAssert.h"


PlaylistGuiFactory::PlaylistGuiFactory(QObject *parent) :
   QObject(parent)
{
}

MediaPositionSlider *PlaylistGuiFactory::buildSeekbar(IF_MediaEngineInterface *engine, QWidget *parent)
{
   Q_ASSERT( engine != NULL);

   MediaPositionSlider *positionSlider = new MediaPositionSlider( parent);

   connect( engine, SIGNAL(totalTimeChanged(qint64)), positionSlider, SLOT(setDurationMs(qint64)) );
   connect( engine, SIGNAL(tick(qint64)), positionSlider, SLOT(setPositionMs(qint64)) );

   connect( positionSlider, SIGNAL(positionChangeRequested(qint64)),
            engine, SLOT(onUserPositionRequested(qint64)) );

   return positionSlider;
}

VolumeSlider *PlaylistGuiFactory::buildVolumeBar(IF_MediaEngineInterface *engine,
                                                 QBoxLayout *container)
{
   Q_ASSERT( engine != NULL);

   Qt::Orientation orientation;
   orientation = (container->direction() <= QBoxLayout::RightToLeft) ?
                    Qt::Horizontal : Qt::Vertical;

   VolumeSlider *volumeSlider = new VolumeSlider( *engine, orientation, container);
   return volumeSlider;
}

AudioVideoPlayBar *PlaylistGuiFactory::buildAudioVideoPlaybar( IF_MediaEngineInterface *engine,
                                                               QWidget *parent)
{
   T_ASSERT( engine != NULL);

   MediaPositionSlider *positionSlider = buildSeekbar( engine, parent);
   T_ASSERT( positionSlider != NULL);
   AudioVideoPlayBar *playbar = new AudioVideoPlayBar( *engine, *positionSlider, parent);

   return playbar;
}

PicturePlaybar *PlaylistGuiFactory::buildPicturePlaybar( IF_PictureEngineInterface * engine,
                                                         QWidget * parent)
{
   return new PicturePlaybar( engine, parent);
}

PlaylistBar * PlaylistGuiFactory::buildPlaylistBar( AudioVideoPlayBar * audioVideoBar,
                                                    PicturePlaybar * pictureBar,
                                                    MediaListModel * mediaList,
                                                    QWidget * parent)
{
   T_ASSERT (audioVideoBar != NULL);
   T_ASSERT (pictureBar != NULL);
   T_ASSERT (mediaList != NULL);
   return new PlaylistBar( *audioVideoBar, *pictureBar, *mediaList, parent);
}

ActionListView *PlaylistGuiFactory::buildPlaylistView( PlaylistBar *playbar,
                                                       QAbstractListModel *model,
                                                       ActionListController *actionController,
                                                       QWidget *parent)
{
   PlaylistPainter *painter = new PlaylistPainter();
   ActionListView *playlistView = new PlaylistView( *actionController, painter, parent);

   playlistView->setModel( model);
   playlistView->setActionBar( playbar);
   playlistView->setContextMenuPolicy( Qt::CustomContextMenu);

   return playlistView;
}

void PlaylistGuiFactory::buildPlaylistPanel( IF_MediaEngineInterface *engine,
                                             AudioVideoAutomation *automation,
                                             ActionListView *playlistView, FileInport *fileInport,
                                             QLayout *container)
{
   QCommonStyle style;
   container->setContentsMargins( 2,2,2,2);

   QWidget *toolbar = new QWidget( container->parentWidget());
   toolbar->setLayout( new QHBoxLayout());
   toolbar->layout()->setContentsMargins( 2,2,2,2);

   MediaPositionSlider *seekBar = buildSeekbar( engine, container->parentWidget());
   container->addWidget( seekBar);

   /* 'fader' button */
   QPushButton *faderButton = new QPushButton( QIcon(IconPath("fade_out.png")),
                                               QString(), toolbar);
   faderButton->setToolTip( tr("start/stop volume fading"));
   faderButton->setFocusPolicy(Qt::NoFocus);
   connect( faderButton, SIGNAL(clicked()), automation, SLOT(toggleFader()) );
   toolbar->layout()->addWidget( faderButton);

   /* 'default voume' button */
   QPushButton *defaultVolumeButton = new QPushButton( QIcon(IconPath("def_vol.png")),
                                                       QString(), toolbar);
   defaultVolumeButton->setToolTip( tr("apply default volume"));
   defaultVolumeButton->setFocusPolicy(Qt::NoFocus);
   connect( defaultVolumeButton, SIGNAL(clicked()), automation, SLOT(applyDefaultVolume()) );
   toolbar->layout()->addWidget( defaultVolumeButton);

   /* default volume spinbox */
   QSpinBox *defaultVolumeSpinbox = new QSpinBox( container->parentWidget());
   defaultVolumeSpinbox->setRange( 0, 100);
   defaultVolumeSpinbox->setValue( automation->defaultVolume());
   connect( defaultVolumeSpinbox, SIGNAL(valueChanged(int)),
            automation, SLOT(defineDefaultVolume(int)) );
   toolbar->layout()->addWidget( defaultVolumeSpinbox);

   toolbar->layout()->addItem( new QSpacerItem( 1,1, QSizePolicy::Expanding));

   /* 'open media' button */
   QPushButton *openMediaButton = new QPushButton( QIcon(IconPath("open_music.png")),
                                                 QString(), toolbar);
   openMediaButton->setToolTip( tr("open a dialog to load new media files"));
   openMediaButton->setFocusPolicy(Qt::NoFocus);
   connect( openMediaButton, SIGNAL(clicked()), fileInport, SLOT(openTracksDialog()) );
   toolbar->layout()->addWidget( openMediaButton);

   /* 'shift up' button */
   QPushButton *shiftUpButton = new QPushButton( style.standardIcon(QStyle::SP_ArrowUp),
                                                 QString(), toolbar);
   shiftUpButton->setToolTip( tr("bring focused element one position above"));
   shiftUpButton->setFocusPolicy(Qt::NoFocus);
   connect( shiftUpButton, SIGNAL(clicked()), playlistView, SLOT(shiftFocusedUp()) );
   toolbar->layout()->addWidget( shiftUpButton);

   /* 'shift down' button */
   QPushButton *shiftDownButton = new QPushButton( style.standardIcon(QStyle::SP_ArrowDown),
                                                   QString(), toolbar);
   shiftDownButton->setToolTip( tr("bring focused element one position below"));
   shiftDownButton->setFocusPolicy(Qt::NoFocus);
   connect( shiftDownButton, SIGNAL(clicked()), playlistView, SLOT(shiftFocusedDown()) );
   toolbar->layout()->addWidget( shiftDownButton);

   container->addWidget( toolbar);
   container->addWidget( playlistView);
}
